<?php
/**
 * BootAdmin is committed to providing solutions for quickly building web applications
 * Please view the LICENSE file that was distributed with this source code,
 * For the full copyright and license information.
 * Thank you very much for using BootAdmin.
 *
 * @Author G.r<root@BootAdmin.com>
 */

declare (strict_types=1);

namespace app\common\service;

use app\common\model\File;
use think\Exception;
use think\facade\Event;
use think\facade\Filesystem;

/**
 * 上传类
 */
class Upload
{
    /**
     * 上传文件
     * @param $cid
     * @param int $sourceId
     * @param int $source
     * @param string $saveDir
     * @return array
     * @throws Exception
     */
    public static function file($cid, int $sourceId = 0, int $source = File::ADMIN, string $saveDir = 'uploads'): array
    {
        try {
            // 获取配置及文件对象
//            $config = get_sys_config('upload');
            $config = [
                'ext'   =>  'jpg,png,gif,jpeg,zip,txt,mp4',
                'size'  =>  '10000MB',
                'type'  =>  'local'
            ];
            $file = request()->file('file');

            // 校验文件是否存在
            $fileModel = File::where('sha1', $file->sha1())->find();
            if (!empty($fileModel)) {
                // 写入数据库中
                $fileData = File::create([
                    'cid'         => $cid,
                    'source_id'   => $sourceId,
                    'source'      => $source,
                    'type'        => $fileModel->type,
                    'uuid'        => create_guid($file->sha1()),
                    'storage'     => $fileModel->storage,
                    'name'        => $file->getOriginalName(),
                    'path'         => $fileModel->path,
                    'sha1'        => $file->sha1(),
                    'create_time' => time(),
                ]);

                // 返回结果
                $data = [
                    'id'   => $fileData['id'],
                    'cid'  => $fileData['cid'],
                    'type' => $fileData['type'],
                    'name' => $fileData['name'],
                    'uuid'  => $fileData['uuid'],
                    'uri'  => self::getUrl($fileData['uuid'])
                ];
                Event::trigger('uploadSuccess', $data);
                return $data;
            }

            // 校验上传文件后缀
            $ext = explode(',', $config['ext']);
            if (!in_array(strtolower($file->extension()), $ext)) {
                throw new Exception("不允许上传". $file->extension() . "文件");
            }

            // 校验上传文件大小
            $size = file_unit_to_byte($config['size']);
            if ($file->getFileInfo()->getSize() > $size) {
                throw new Exception("文件大小超出限制，文件大小：". round($file->getFileInfo()->getSize() / pow(1024, 2), 2) ."MB，最大限制:". round($size / pow(1024, 2), 2) . "MB");
            }

            // 上传文件
            $savename = Filesystem::disk('public')->putFile($saveDir, $file, 'md5');

            // 检查上传类型
            $type = $file->getType();
            if (strpos($type, 'image') !== -1) {
                $type = File::IMAGE;
            } elseif (strpos($type, 'video') !== -1) {
                $type = File::VIDEO;
            } else {
                $type = File::FILE;
            }

            // 写入数据库中
            $fileData = File::create([
                'cid'         => $cid,
                'source_id'   => $sourceId,
                'source'      => $source,
                'type'        => $type,
                'uuid'        => create_guid($file->sha1()),
                'storage'     => $config['type'],
                'name'        => $file->getOriginalName(),
                'path'         => str_replace("\\","/", $savename),
                'sha1'        => $file->sha1(),
                'create_time' => time(),
            ]);

            // 返回结果
            $data = [
                'id'   => $fileData['id'],
                'cid'  => $fileData['cid'],
                'type' => $fileData['type'],
                'name' => $fileData['name'],
                'uuid' => $fileData['uuid'],
                'uri'  => self::getUrl($fileData['uuid'])
            ];
            Event::trigger('uploadSuccess', $data);
            return $data;

        } catch (Exception $e) {
            throw new Exception($e->getMessage());
        }
    }

    /**
     * 获取附件URL
     * @param $uuid
     * @return string
     */
    public static function getUrl($uuid): string
    {
        return url('ajax/file', ['uuid' => $uuid], true, true)->build();
    }
}